<template>
  <div class="table-header">
    <div class="table-header-left">
      <div v-if="props.buttons.includes('refresh')">
        <el-tooltip effect="dark" content="刷新" placement="top">
          <el-button type="primary" color="#40485b" @click="handleRefresh">
            <el-icon style="color: #fff; font-size: 18px"><Refresh /></el-icon>
          </el-button>
        </el-tooltip>
      </div>
      <div v-btn-permission="`${props.rolePrefix}:create`" v-if="props.buttons.includes('add')">
        <el-tooltip effect="dark" content="新增" placement="top">
          <el-button type="primary" color="#526ff8" @click="handleCreate">
            <el-icon style="color: #fff; font-size: 18px"><Plus /></el-icon>
            <span>新增</span>
          </el-button>
        </el-tooltip>
      </div>
      <div v-btn-permission="`${props.rolePrefix}:delete`" v-if="props.buttons.includes('delete')">
        <el-tooltip effect="dark" content="删除" placement="top">
          <el-button type="danger" @click="handleBatchDelete">
            <el-icon style="color: #fff; font-size: 18px"><Delete /></el-icon>
            <span>删除</span>
          </el-button>
        </el-tooltip>
      </div>
    </div>
    <div class="table-header-right">
      <el-input
        v-if="props.buttons.includes('quickSearch')"
        v-model="key"
        placeholder="请输入关键字搜索"
        clearable
        style="width: 200px"
        @input="onInput"
      />
      <div v-if="props.buttons.includes('comSearch')">
        <el-tooltip effect="dark" content="通用搜索" placement="top">
          <el-button @click="handleComSearchClick">
            <el-icon style="color: #000; font-size: 18px"><Search /></el-icon>
          </el-button>
        </el-tooltip>
      </div>
      <div v-if="props.buttons.includes('colSetting')">
        <el-tooltip effect="dark" content="列设置" placement="top">
          <el-dropdown trigger="click" :hide-on-click="false" :teleported="false">
            <el-button>
              <el-icon style="font-size: 18px"><Menu /></el-icon>
            </el-button>
            <template #dropdown>
              <el-dropdown-menu>
                <VueDraggable v-model="allColumns" :animation="150" filter=".no-drag" handle=".sort" @end="onDragEnd">
                  <template v-for="column in allColumns" :key="column.prop">
                    <el-dropdown-item>
                      <el-checkbox
                        v-model="column.visible"
                        :class="{ 'no-drag': column.prop === 'option' }"
                        @change="handleColumnChange"
                      >
                        {{ column.label }}
                        <el-icon v-if="column.prop !== 'option'" class="sort" style="font-size: 14px">
                          <Sort />
                        </el-icon>
                      </el-checkbox>
                    </el-dropdown-item>
                  </template>
                </VueDraggable>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </el-tooltip>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue"
import _ from "lodash"
import { VueDraggable } from "vue-draggable-plus"
import { Plus, Refresh, Search, Delete, Menu, Sort } from "@element-plus/icons-vue"
import useHomeStore from "@/stores/home"

interface TableColumn extends Column {
  visible: boolean
}

// 表格列
const columns = defineModel<Column[]>("columns", { required: true })

const props = defineProps<{
  buttons: string[] // 显示的按钮列表
  rolePrefix: string // 权限标识前缀
  tableId: string // 表格唯一id
}>()

const emit = defineEmits<{
  refresh: []
  create: []
  batchDelete: []
  change: [value: string]
}>()

const homeStore = useHomeStore()

// 快速搜索的关键字
const key = ref("")
// 全部列
const allColumns = ref<TableColumn[]>([])

onMounted(() => {
  initColumn()
})

/**
 * 初始化列
 */
const initColumn = () => {
  // 获取缓存中的列
  const originColumnStr = localStorage.getItem(`tableColumns_${props.tableId}`)
  // 增加是否显示的属性
  const newColumns: TableColumn[] = columns.value.map((item) => {
    return {
      ...item,
      visible: true // 是否显示
    }
  })

  let originColumn: TableColumn[] = []
  if (originColumnStr) {
    // 如果缓存中有，解析缓存中的列
    const originColumnCache = JSON.parse(originColumnStr) as TableColumn[]

    // 以新列为准，利用缓存中的列覆盖新列中的属性，再返回显示的列。
    // 保证了新列增加、修改、删除列后也能正确显示
    const mergeColumns = newColumns.map((column) => {
      const findColumn = originColumnCache.find((item) => item.prop === column.prop)
      return findColumn ? { ...column, ...findColumn } : { ...column }
    })

    // 按 originColumnCache 的顺序排序，新增列追加到末尾
    const cachedOrder = originColumnCache.map((item) => item.prop)
    const sortedColumns = [...mergeColumns].sort((a, b) => {
      const indexA = cachedOrder.indexOf(a.prop)
      const indexB = cachedOrder.indexOf(b.prop)

      if (indexA !== -1 && indexB !== -1) return indexA - indexB // 都在缓存里，按缓存顺序排
      if (indexA !== -1) return -1 // a 在缓存里，a 排前面
      if (indexB !== -1) return 1 // b 在缓存里，b 排前面
      return 0 // 都不在缓存里，保持原顺序（新增列）
    })

    const finalColumns = sortedColumns.filter((item) => item.visible)
    originColumn = finalColumns

    // 全部列不需要过滤
    allColumns.value = sortedColumns
    // 更新缓存中的值
    localStorage.setItem(`tableColumns_${props.tableId}`, JSON.stringify(allColumns.value))
  } else {
    // 如果没有缓存，默认显示所有列
    allColumns.value = newColumns
    originColumn = newColumns
  }

  // 缓存中有，覆盖初始的列
  columns.value = originColumn
}

/**
 * 列的复选框改变
 */
const handleColumnChange = () => {
  // 筛选选中的列
  columns.value = allColumns.value.filter((column) => column.visible)
  // 缓存操作后的表格列
  localStorage.setItem(`tableColumns_${props.tableId}`, JSON.stringify(allColumns.value))
}

/**
 * 拖拽结束
 */
const onDragEnd = () => {
  // 拖拽后的列
  columns.value = allColumns.value
  // 缓存操作后的表格列
  localStorage.setItem(`tableColumns_${props.tableId}`, JSON.stringify(allColumns.value))
}

/**
 * 刷新数据
 */
const handleRefresh = () => {
  emit("refresh")
}

/**
 * 新增
 */
const handleCreate = () => {
  emit("create")
}

/**
 * 批量删除
 */
const handleBatchDelete = () => {
  emit("batchDelete")
}

/**
 * 根据关键字快速搜索
 */
const onInput = _.debounce((val: string) => {
  emit("change", val)
}, 300)

/**
 * 控制通用搜索的显示和隐藏
 */
const handleComSearchClick = () => {
  homeStore.setShowComSearchAction()
}
</script>

<style lang="scss" scoped>
.table-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;

  &-left {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  &-right {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  :deep(.el-checkbox) {
    width: 100%;

    .el-checkbox__label {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 8px;
    }
  }
}
</style>
